#ifndef _PHYLIP_H_
#define _PHYLIP_H_

/* version 3.6. (c) Copyright 1993-2004 by the University of Washington.
   Written by Joseph Felsenstein, Akiko Fuseki, Sean Lamont, Andrew Keeffe,
   Mike Palczewski, Doug Buxton and Dan Fineman.
   Permission is granted to copy and use this program provided no fee is
   charged for it and provided that this copyright notice is not removed. */

#define VERSION "3.61"


#include <cstdio>
#include <cstdlib>
#include <vector>
#include <string>
#include <istream>
#include <progress_indicator.h>


#define Char        char      /* Characters (not bytes) */




#define down            2

#define smoothings      4    /* number of passes through smoothing algorithm */
#define iterations      4    /* number of iterates for each branch           */
#define sm_epsilon         0.0001  /* small number used in makenewv */
#define EPSILON         0.00001  /* small number used in hermite root-finding */
#define initialv        0.1  /* starting branch length unless otherwise */
#define over            60   /* maximum width all branches of tree on screen */
#define SQRTPI 1.7724538509055160273
#define SQRT2  1.4142135623730950488







typedef struct node
{
	struct node *next, *back;
	std::string nayme;
	long index;
	double xcoord, ycoord;
	long ymin, ymax;					   // used by printree        -plc   //
	double v;			
	bool tip;
	bool iter;					 // iter used in dnaml, fitch & restml   //
	std::vector<double>	d;
	std::vector<double>	w;					 // for distance matrix programs           //
	double dist;				   // dist used in fitch                     //
	node()
	:next(0), back(0), index(0), xcoord(0.0), ycoord(0.0),
        ymin(0), ymax(0),
		v(0.0),
		tip(false),
		iter(true),
		dist(0.0)
	{
	}
} node;

typedef node **pointarray;

struct tree
{
	void alloctree(unsigned cnt_species);
	void allocw();
	void allocd();
	void setuptree();
	tree(unsigned spp,
			bool min_evolution,
			bool neg_branches_allowed,
			double powr,
			t_progress_indicator& dots_):

				spp(0), nonodes(0), likelihood(-1.0), start(0), root(0),
				best_tree(0), prev_tree(0),
				minev(min_evolution),
				negallowed(neg_branches_allowed),
				power(powr), dots(dots_)
	{	
		if (minev)
			negallowed = true;
		alloctree(spp);}
	tree(const tree& other):spp(other.spp), nonodes(0), likelihood(-1.0), start(0), root(0),
			best_tree(0), prev_tree(0),
			minev(other.minev),
			negallowed(other.negallowed),
			power(other.power),
			dots(other.dots)
	{	alloctree(spp);}
	unsigned spp;
	unsigned nonodes;
	std::vector<node> nodes;
	std::vector<node*> nodep;
	double likelihood;
	node *start;					// start used in dnaml & restml //
	node *root;						// root used in dnamlk //
	tree* best_tree;
	tree* prev_tree;
	bool minev;
	bool negallowed;
	double power;
	t_progress_indicator& dots;
};


void init_signals();
long count_sibs (node *p);
void   hookup(node *, node *);
void treeread2 (std::istream& treefile, node **root, pointarray treenode,
				bool lngths, unsigned no_species,
				const std::vector<std::string>& nayme);


#endif // _PHYLIP_H_ //
